package com.css.bjdt_report.executive;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ExecutorService;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.css.bjdt_report.cell.entity.Cell;
import com.css.bjdt_report.cell.entity.CellData;
import com.css.bjdt_report.cell.service.CellDataService;
import com.css.bjdt_report.executive.report.ReportSession;
import com.css.bjdt_report.report.entity.RptTemplateUnitRela;
import com.css.bjdt_report.util.spring.SpringContextHolder;

public class Executors {
	private static Executors instance;

	private ExecutorService pool;

	private ReportSession session;

	private CellDataService cellDataService = SpringContextHolder.getBean(CellDataService.class);
	
	private static Log logger = LogFactory.getLog(Executors.class);

	private Executors() {
		int cpuNum = Runtime.getRuntime().availableProcessors();
		pool = java.util.concurrent.Executors.newFixedThreadPool(cpuNum);
	}

	public static synchronized Executors getInstance() {
		if (instance == null) {
			instance = new Executors();
		}
		return instance;
	}

	public void execute(List<RptTemplateUnitRela> templateUnitRelas, boolean isSyn) {
		if (!isSyn) {
			pool.execute(new ExecuteThread(templateUnitRelas));
		} else {
			executeByUnit(templateUnitRelas);
		}
	}

	private void executeByUnit(List<RptTemplateUnitRela> templateUnitRelas) {
		if (templateUnitRelas != null && templateUnitRelas.size() > 0) {
			List<CellData> cellDatas = new ArrayList<CellData>();
			String annualId = templateUnitRelas.get(0).getAnnualId();
			for (RptTemplateUnitRela templateUnitRela : templateUnitRelas) {
				List<Cell> cells = (List<Cell>) session.getCell(templateUnitRela.getTemplateId());
				// 按指标取值优先级排序
				Collections.sort(cells, new Comparator<Cell>() {
					@Override
					public int compare(Cell cell1, Cell cell2) {
						return cell2.getCellLevel() - cell1.getCellLevel();
					}
				});
				List<CellData> list = new ArrayList<CellData>();
				// 把指标值存储到session里供其他依赖指标使用
				session.putCellData(templateUnitRela.getTemplateId(), list);
				for (Cell cell : cells) {
					String cellValue = cell.getExecutor().execute(cell, session);
					CellData cellData = new CellData(cell, cellValue, templateUnitRela.getUnitId(), templateUnitRela.getTemplateId());
					list.add(cellData);
				}
				cellDatas.addAll(list);
				// 按年度id、党组织id、报表id删除指标数据(只删除统计类型、计算类型、引用类型指标)
				cellDataService.deleteCellData(annualId, templateUnitRela.getUnitId(), templateUnitRela.getTemplateId());
			}			
			cellDataService.batchInsertCellData(annualId, cellDatas);
		}
	}

	public void setSession(ReportSession session) {
		this.session = session;
	}

	class ExecuteThread extends Thread {
		private List<RptTemplateUnitRela> templateUnitRelas;

		public ExecuteThread(List<RptTemplateUnitRela> templateUnitRelas) {
			this.templateUnitRelas = templateUnitRelas;
		}

		@Override
		public void run() {
			executeByUnit(templateUnitRelas);
		}

	}
}
